<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" lang="en"></meta>
  <title>OSM3S Experimental Diff</title>
  <script src="http://openlayers.org/api/2.13.1/OpenLayers.js"></script>
  <script src="http://overpass-api.de/OpenStreetMap.js"></script>
  <script src="http://overpass-api.de/overpass.js"></script>
  <script type="text/javascript">
      var lat = 50.734;
      var lon = 7.100;
      var zoom = 18;
      var data_url = "http://overpass-api.de/api/interpreter";
      var map;

      var layer = false;
      var layerMapnik = false;

      function refreshData()
      {
          if (layer)
              map.removeLayer(layer);
          clearTextualResults();

          setStatus("Loading data");

          var mindate = fullDate(new Date());
          var select_mindate = document.getElementById("select_mindate");
          if (select_mindate)
              mindate = select_mindate.value;

          var maxdate = "";
          var select_maxdate = document.getElementById("select_maxdate");
          if (select_maxdate)
              maxdate = select_maxdate.value;
          if (maxdate != "")
              maxdate = ",\"" + maxdate + "\"";

          //Initialise the vector layer using OpenLayers.Format.OSM
          var styleMap = new OpenLayers.StyleMap({
              strokeColor: "blue",
              strokeOpacity: 0.5,
              strokeWidth: 6,
              pointRadius: 10,
              fillColor: "blue",
              fillOpacity: 0.25
          });

          var lookup = {
              "old": { strokeColor: "red", fillColor: "red" },
              "new": { strokeColor: "green", fillColor: "green" }
          }

          styleMap.addUniqueValueRules("default", "state", lookup);
          layer = new OpenLayers.Layer.Vector("Polygon", {
              strategies: [new OpenLayers.Strategy.Fixed()],
              protocol: new OpenLayers.Protocol.HTTP({
                  url: data_url + "?data=[adiff:\"" + mindate + "\"" + maxdate
                      + "];(node(bbox);way(bbox);relation(bbox););out meta geom(bbox);&bbox=" + layerMapnik.getExtent().transform("EPSG:900913", "EPSG:4326").toBBOX(),
                  format: new OSMDiffFormat({
                      extent: layerMapnik.getExtent().transform("EPSG:900913", "EPSG:4326"),
                      setStatus: function(status) { setStatus(status); },
                      pushTextualResult: function(feature) { collectFeature(feature); }
                      })
              }),
              styleMap: styleMap,
              projection: new OpenLayers.Projection("EPSG:4326")
          });

          map.addLayers([layer]);
      }


      function fullDate(date)
      {
          var result = date.getUTCFullYear();
          result += "-";

          var month = date.getUTCMonth() + 1;
          result += (month <= 9 ? ("0" + month) : month);

          result += "-";

          var day = date.getUTCDate();
          result += (day <= 9 ? ("0" + day) : day);

          result += "T";

          var hour = date.getUTCHours();
          result += (hour <= 9 ? ("0" + hour) : hour);

          result += ":";

          var minute = date.getUTCMinutes();
          result += (minute <= 9 ? ("0" + minute) : minute);

          result += ":";

          var second = date.getUTCSeconds();
          result += (second <= 9 ? ("0" + second) : second);

          result += "Z";

          return result;
      }

      function init()
      {
          map = new OpenLayers.Map ("map", {
          controls:[
              new OpenLayers.Control.Navigation(),
              new OpenLayers.Control.PanZoomBar(),
              new OpenLayers.Control.LayerSwitcher(),
              new OpenLayers.Control.Attribution()],
              maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
              maxResolution: 156543.0399,
              numZoomLevels: 19,
              units: 'm',
              projection: new OpenLayers.Projection("EPSG:900913"),
              displayProjection: new OpenLayers.Projection("EPSG:4326")
          } );

          layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
          map.addLayer(layerMapnik);

          var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));

          map.setCenter (lonLat, zoom);

          var yesterday = new Date(new Date().getTime() - 86400*1000);
          var select_mindate = document.getElementById("select_mindate");
          if (select_mindate)
              select_mindate.value = fullDate(yesterday);

          refreshData();
      }

      var textual_old = "";
      var textual_geometry_changed = "";
      var textual_new = "";
      var textual_tags_changed = "";
      var textual_unchanged = "";
      var old_feat = false;

      function setStatus(status)
      {
          var status_line = document.getElementById("status_line");
          if (status_line)
              status_line.innerHTML = status;

          if (status == "Ready")
          {
              if (old_feat)
                  pushTextualResult(old_feat, false);
              old_feat = false;

              var textual_results_html = document.getElementById("textual_results");
              if (textual_results_html)
                  textual_results_html.innerHTML =
                      textual_old + textual_geometry_changed + textual_new
                      + textual_tags_changed + textual_unchanged;
          }
      }

      function clearTextualResults()
      {
          textual_old = "";
          textual_geometry_changed = "";
          textual_new = "";
          textual_tags_changed = "";
          textual_unchanged = "";
          var textual_results_html = document.getElementById("textual_results");
          if (textual_results_html)
              textual_results_html.innerHTML = "";
      }


      function equal_geom(lhs, rhs)
      {
          if (lhs.x || lhs.y || rhs.x || rhs.y)
              return (lhs.x && lhs.y && rhs.x && rhs.y && lhs.x == rhs.x && lhs.y == rhs.y);

          if (rhs.components && !lhs.components)
              return false;
          if (lhs.components && (!rhs.components || lhs.components.length != rhs.components.length))
              return false;

          for (var i = 0; i < lhs.components.length; ++i)
          {
              if (!equal_geom(lhs.components[i], rhs.components[i]))
                  return false;
          }
          return true;
      }


      function pushTextualResult(old_feat, new_feat)
      {
          if (old_feat && new_feat)
          {
              var geometry_changed = false;
              if (old_feat.geometry && new_feat.geometry)
                  geometry_changed = !equal_geom(old_feat.geometry, new_feat.geometry);
              else
                  geometry_changed = (old_feat.geometry || new_feat.geometry);

              var taglist = "";
              var tags_changed = false;

              if (old_feat.tags)
              {
                  for (tag in old_feat.tags)
                  {
                      if (!new_feat.tags || new_feat.tags[tag] != old_feat.tags[tag])
                      {
                          taglist += "<br/>- &nbsp;<span style=\"color:red\">"
                              + tag + "=" + old_feat.tags[tag] + "</span>";
                          tags_changed = true;
                      }
                  }
              }

              if (new_feat.tags)
              {
                  for (tag in new_feat.tags)
                  {
                      if (!old_feat.tags || old_feat.tags[tag] != new_feat.tags[tag])
                      {
                          taglist += "<br/>+ &nbsp;<span style=\"color:green\">"
                              + tag + "=" + new_feat.tags[tag] + "</span>";
                          tags_changed = true;
                      }
                  }
              }

              if (old_feat.tags && new_feat.tags)
              {
                  for (tag in new_feat.tags)
                  {
                      if (old_feat.tags && old_feat.tags[tag] == new_feat.tags[tag])
                          taglist += "<br/>&nbsp; &nbsp;" + tag + "=" + new_feat.tags[tag];
                  }
              }

              var result = "<br/><br/>";
              if (geometry_changed)
                  result += "reshaped ";
              else if (tags_changed)
                  result += "retagged ";
              else
                  result += "changed ";

              if (old_feat.type && old_feat.osm_id)
                  result += "<a href=\"http://osm.org/browse/"
                      + old_feat.type + "/" + old_feat.osm_id + "\"/>"
                      + old_feat.type + " " + old_feat.osm_id + "</a>";

              if (geometry_changed)
                  textual_geometry_changed += result + taglist;
              else if (tags_changed)
                  textual_tags_changed += result + taglist;
              else
                  textual_unchanged += result + taglist;
          }
          else if (old_feat)
          {
              var result = "<br/><br/><span style=\"color:red\">old ";

              if (old_feat.type && old_feat.osm_id)
                  result += "<a href=\"http://osm.org/browse/"
                      + old_feat.type + "/" + old_feat.osm_id + "\"/>"
                      + old_feat.type + " " + old_feat.osm_id + "</a>";

              result += "</span>";

              if (old_feat.tags)
              {
                  for (tag in old_feat.tags)
                      result += "<br/>" + tag + "=" + old_feat.tags[tag];
              }

              textual_old += result;
          }
          else
          {
              var result = "<br/><br/><span style=\"color:green\">new ";

              if (new_feat.type && new_feat.osm_id)
                  result += "<a href=\"http://osm.org/browse/"
                      + new_feat.type + "/" + new_feat.osm_id + "\"/>"
                      + new_feat.type + " " + new_feat.osm_id + "</a>";

              result += "</span>";

              if (new_feat.tags)
              {
                  for (tag in new_feat.tags)
                      result += "<br/>" + tag + "=" + new_feat.tags[tag];
              }

              textual_new += result;
          }
      }

      function collectFeature(feature)
      {
          if (feature.data && feature.data.state && feature.data.state == "old")
          {
              if (old_feat)
                  pushTextualResult(old_feat, false);
              old_feat = feature;
          }
          else if (old_feat)
          {
              if (old_feat.osm_id && old_feat.osm_id == feature.osm_id)
                  pushTextualResult(old_feat, feature);
              else
              {
                  pushTextualResult(old_feat, false);
                  pushTextualResult(false, feature);
              }
              old_feat = false;
          }
          else
              pushTextualResult(false, feature);
      }

  </script>
</head>
<body onload="init()">
  <div id="control_bar" class="control_bar" style="position:absolute; top:0%; left:0%; height:100%; width:30%; z-index:1">
    <form action="#" acceptCharset="UTF-8" onsubmit="alert(&nbsp;foo&nbsp;);">
      <input type="text" id="select_mindate" value=""></input>
      <input type="text" id="select_maxdate" value=""></input>
      <input type="submit" value="Fetch data" onclick="refreshData()"></input>
    </form>
    <div id="status_line" class="status_line">Ready</div>
    <div id="textual_results" class="textual_results"><br/>(no entries)</div>
  </div>
  <div id="map" class="smallmap" style="position:absolute; top:0%; left:30%; height:100%; width:70%; z-index:1"></div>

</body>
</html>


